package com.andyou.modules.sys.web;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.andyou.common.config.Global;
import com.andyou.common.mapper.JsonMapper;
import com.andyou.common.persistence.Page;
import com.andyou.common.utils.DateUtils;
import com.andyou.common.utils.GridVO;
import com.andyou.common.utils.StringUtils;
import com.andyou.common.utils.excel.ExportExcel;
import com.andyou.common.web.BaseController;
import com.andyou.modules.sys.entity.Office;
import com.andyou.modules.sys.entity.User;
import com.andyou.modules.sys.service.OfficeService;
import com.andyou.modules.sys.service.UserService;
import com.andyou.modules.sys.utils.DictUtils;
import com.andyou.modules.sys.utils.UserUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 机构Controller
 * 
 * @author ThinkGem
 * @version 2013-5-15
 */
@Controller
@RequestMapping(value = "${adminPath}/sys/office")
public class OfficeController extends BaseController {

	@Autowired
	private OfficeService officeService;
	@Autowired
	private UserService userService;

	@ModelAttribute("office")
	public Office get(@RequestParam(required = false) String id,
			@RequestParam(required = false) boolean isStop) {
		if (StringUtils.isNotBlank(id) && !isStop) {
			return officeService.get(id);
		} else {
			return new Office();
		}
	}

	/* @RequiresPermissions("sys:office:view") */
	@RequestMapping(value = { "officeIndex" })
	public String index(Office office, Model model) {
		// model.addAttribute("list", officeService.findAll());
		return "modules/sys/officeIndex";
	}

	/* @RequiresPermissions("sys:office:view") */
	@RequestMapping(value = { "dialogOfficeIndex" })
	public String dialogOfficeIndex(Office office, Model model) {
		// model.addAttribute("list", officeService.findAll());
		return "modules/sys/dialogOfficeIndex";
	}

	/* @RequiresPermissions("sys:office:view") */
	@RequestMapping(value = { "dialogCompanyList" })
	public String dialogCompanyList(Office office, HttpServletRequest request,
			HttpServletResponse response, Model model) {
		Page<Office> page_office = new Page<Office>(request, response);
		page_office.setPageSize(10);
		page_office.setIsModifyedPageSize(false);
		Page<Office> page = officeService.findPage(page_office, office);
		model.addAttribute("page", page);
		return "modules/sys/dialogCompanyList";
	}


	@RequiresPermissions("sys:office:view")
	@RequestMapping(value = { "list" })
	public String list(Office office, Model model, HttpServletRequest request, HttpServletResponse response) {
		//office.setShowMyOffice(false);
		//Page<Office> page = officeService.findPage(new Page<Office>(request, response), office);
		//model.addAttribute("page", page);
		return "modules/sys/officeList";
	}

	@RequiresPermissions("sys:office:view")
	@RequestMapping(value = "form")
	public String form(Office office,boolean someLeave,Model model) {
		User user = UserUtils.getUser();
		if (office.getParent() == null || office.getParent().getId() == null) {
			office.setParent(user.getOffice());
		}
		office.setParent(officeService.get(office.getParent().getId()));
		if (office.getArea() == null) {
			office.setArea(user.getOffice().getArea());
		}
		// 自动获取排序号
		if (StringUtils.isBlank(office.getId()) && office.getParent() != null) {
			int size = 0;
			List<Office> list = officeService.findAll(office);
			for (int i = 0; i < list.size(); i++) {
				Office e = list.get(i);
				if (e.getParent() != null && e.getParent().getId() != null
						&& e.getParent().getId().equals(office.getParent().getId())) {
					size++;
				}
			}
			if("3".equals(office.getGrade())) {
				office.setCode(office.getParent().getCode()
						+ "-" + StringUtils.leftPad(String.valueOf(size > 0 ? size + 1 : 1), 2, "0"));
			}else if("4".equals(office.getGrade())) {
				office.setCode(office.getParent().getCode()
						+ StringUtils.leftPad(String.valueOf(size > 0 ? size + 1 : 1), 2, "0"));
			}
			
		}
		
		if (someLeave) {
			office.setName(null);
			office.setCode(null);
			office.setDoSort(null);
			office.setId(null);
		}
		model.addAttribute("office", office);
		return "modules/sys/officeForm";
	}

	@RequiresPermissions(value={"sys:office:edit","sys:office:create"},logical=Logical.OR)
	@RequestMapping(value = "save")
	public String save(Office office, Model model, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		if (Global.isDemoMode()) {
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/sys/office/list";
		}
		if (!beanValidator(model, office)) {
			return form(office,false, model);
		}
		
		//新建情况下
		if (StringUtils.isBlank(office.getId())) {
			if (!officeService.checkIsOnlyCode(office.getCode())) {
				addMessage(model, "机构代码："+office.getCode()+"已经存在！");
				return form(office,false, model);
			}
		/**	if (!officeService.checkIsOnlyZipCode(office.getZipCode())) {
				addMessage(model, "机构编码："+office.getCode()+"已经存在！");
				return form(office,false, model);
			} */
		}else{
			//修改情况下：如果和就编码一样则不需要验证，不一样则需要验证
			if (!StringUtils.equals(office.getCode(), office.getCodeOld()) && !officeService.checkIsOnlyCode(office.getCode())) {
				addMessage(model, "机构代码："+office.getCode()+"已经存在！");
				return form(office,false, model);
			}
			/**if (!StringUtils.equals(office.getZipCode(), office.getZipCodeOld()) && !officeService.checkIsOnlyZipCode(office.getZipCode())) {
				addMessage(model, "机构编码："+office.getZipCode()+"已经存在！");
				return form(office,false, model);
			}*/
		}

		officeService.save(office);

		if (office.getChildDeptList() != null) {
			Office childOffice = null;
			for (String id : office.getChildDeptList()) {
				childOffice = new Office();
				childOffice.setName(DictUtils.getDictLabel(id, "sys_office_common", "未知"));
				childOffice.setParent(office);
				childOffice.setArea(office.getArea());
				childOffice.setType("2");
				childOffice.setGrade(String.valueOf(Integer.valueOf(office.getGrade()) + 1));
				childOffice.setUseable(Global.YES);
				officeService.save(childOffice);
			}
		}

		 addMessage(redirectAttributes, "保存成功"); 
		// String id = "0".equals(office.getParentId()) ? "" :
		// office.getParentId();
		//弹框后关闭页面
		//renderStringByJbox(response, "提交成功");
		
		return "redirect:" + adminPath + "/sys/office/list";
	}

	@RequiresPermissions("sys:office:delete")
	@RequestMapping(value = "delete")
	public String delete(Office office, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		if (Global.isDemoMode()) {
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/sys/office/list";
		}
		//if (Office.isRoot(id)){
		// addMessage(redirectAttributes, "删除机构失败, 不允许删除顶级机构或编号空");
		// }else{
		officeService.delete(office);
		// addMessage(redirectAttributes, "删除机构成功");
		// }
		// return "redirect:" + adminPath +
		// "/sys/office/list?id="+office.getParentId()+"&parentIds="+office.getParentIds();
		renderStringByReload(response, "删除标签成功");
		return null;
	}

	/**
	 * 获取机构JSON数据。
	 * 
	 * @param extId
	 *            排除的ID
	 * @param type
	 *            类型（1：公司；2：部门/小组/其它：3：用户）
	 * @param grade
	 *            显示级别
	 * @param parentId
	 *            父类id
	 * @param isReadCache
	 *            是否读取缓存(默认读取)
	 * @param response
	 * @return
	 */
	@RequiresPermissions("user")
	@ResponseBody
	@RequestMapping(value = "treeData")
	public List<Map<String, Object>> treeData(Office office,
			@RequestParam(required = false) String extId,
			@RequestParam(required = false) String type,
			@RequestParam(required = false) Long grade,
			@RequestParam(required = false) String parentId,
			@RequestParam(required = false) Boolean isAll,
			@RequestParam(required = false) String addNote,
			@RequestParam(required = false) Boolean isReadCache, HttpServletResponse response) {

		// 默认读取缓存
		if (isReadCache == null) {
			isReadCache = true;
		}

		if (SecurityUtils.getSubject().hasRole("zcgly")
				&& "1".equals(UserUtils.getUser().getCompany().getGrade())) {
			isAll = true;
		}

		List<Map<String, Object>> mapList = Lists.newArrayList();
		if (!StringUtils.isBlank(type)) {
			office.setType(type);
		}
		
		//新增一条全部的节点
		if(office.isAddNote()){
			Map<String, Object> map1 = Maps.newHashMap();
			map1.put("id", "all");
			map1.put("pId", "");
			map1.put("pIds", "");
			map1.put("name", "全部");
			if (type != null && "3".equals(type)) {
				map1.put("isParent", true);
			}
			mapList.add(map1);
		}

		if (!StringUtils.isBlank(parentId)) {
			Office officeParent = new Office();
			officeParent.setId(parentId);
			office.setParent(officeParent);
		}

		List<Office> list = officeService.findList(office, isAll, isReadCache);

		for (int i = 0; i < list.size(); i++) {
			Office e = list.get(i);
			e.setParentIds(e.getParentIds() == null ? "" : e.getParentIds());
			if ((StringUtils.isBlank(extId) || (extId != null && !extId.equals(e.getId()) && e
					.getParentIds().indexOf("," + extId + ",") == -1))
					&& (type == null || (type != null && (type.equals("1") ? type.equals(e
							.getType()) : true))||"0".equals(e.getType()))
					&& (grade == null || (grade != null && Integer.parseInt(e.getGrade()) <= grade
							.intValue())) && Global.YES.equals(e.getUseable())) {
				Map<String, Object> map = Maps.newHashMap();
				
				map.put("id", e.getId());
				map.put("pId", e.getParentId());
				map.put("pIds", e.getParentIds());
				map.put("name", e.getName());
				map.put("grade", e.getGrade());
				if (type != null && "3".equals(type)) {
					map.put("isParent", true);
				}
				mapList.add(map);
			}
		}
		return mapList;
	}
	
	
	
	/** 
	 * 导出组织机构信息
	 * @param office
	 * @param request
	 * @param response
	 * @param redirectAttributes
	 * @return （参数是否可空/不可空）
	 * @author vikingbin
	 * Date:2016年11月8日；
	 */
	@RequestMapping(value = "export")
	public String exportFile(Office office, HttpServletRequest request, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		try {
			String fileName = "组织机构信息" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
			Page<Office> page_ = new Page<Office>(request, response, -1);
			page_.setPageSize(500000);
			office.setPage(page_);
			page_.setList(officeService.findList(office));
			new ExportExcel("组织机构信息", Office.class).setDataList(page_.getList()).write(response, fileName).dispose();
			return null;
		} catch (Exception e) {
			addMessage(redirectAttributes, "导出数据失败！失败信息：" + e.getMessage());
		}
		return "redirect:" + Global.getAdminPath() + "/sys/officeList";
	}
	
	/**
	 * 获取组织架构列表
	 * @param office
	 * @param request
	 * @param response
	 * @param model
	 * @return （参数是否可空/不可空）
	 * @author vikingbin
	 * Date:2017年1月3日；
	 */
	@ResponseBody
	@RequestMapping(value = { "officeListJson" })
	public String officeListJson(Office office,String myParentId, HttpServletRequest request,
			HttpServletResponse response, Model model) {
		
		if (!StringUtils.isBlank(myParentId)) {
			Office o = new Office();
			o.setId(myParentId);
			office.setParent(o);
		}
	
		Page<Office> page = officeService.findPage(new Page<Office>(request, response,true),
				office);
		model.addAttribute("page", page);

		GridVO gridVO = new GridVO();
		gridVO.setRows(page.getList());
		gridVO.setTotal(page.getCount());
		
		return JsonMapper.getInstance().toJson(gridVO);
	}
	
	@ResponseBody
	@RequestMapping(value = "deleteAjax")
	public String deleteAjax(Office office, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		if (Global.isDemoMode()) {
			return "越权操作，只有超级管理员才能修改此数据！";
		}
		if (Global.isDemoMode()) {
			return "演示模式，不允许操作！";
		}

		boolean hadChild = this.hadChild(office.getId());
		
		if (hadChild) {
			return "删除失败,该组织机构存在下级组织机构，请先删除子机构！";
		}
		if ("1".equals(office.getId())){
			return "删除失败, 不允许删除顶级机构！";
		}
		if("100".equals(office.getId())){
			return "删除失败, 该部门为内置机构不可以被删除！";
		}
		if (userService.hadUserByOffice(office.getId())) {
			return "删除失败, 该机构下面存在用户不允许删除，请先删除用户或者迁移用户！";
		}
		
		officeService.delete(office);
	
		return "删除成功";
	}
	
	@ResponseBody
	@RequestMapping(value = "batchDelete") 
	public String batchDelete(String ids, RedirectAttributes redirectAttributes) {
		
		if (Global.isDemoMode()) {
			return "演示模式，不允许操作！";
		}
		
		if (StringUtils.isBlank(ids)) {
			return "没有可以删除的机构id！";
		}
		
        String[]  officeIdsArr =  ids.split(",");
        List<String> officeIdList = Lists.newArrayList();
        officeIdList = Arrays.asList(officeIdsArr);
        
        for (int i = 0; i < officeIdList.size(); i++) {
    		if (hadChild(officeIdList.get(i))) {
    			return "删除失败,该组织机构存在下级组织机构，请先删除子机构！";
    		}
    		if ("1".equals(officeIdList.get(i))){
    			return "删除机构失败, 不允许删除顶级机构！";
    		}
    		if("100".equals(officeIdList.get(i))){
    			return "删除失败, 该部门为内置机构不可以被删除！";
    		}
    		if (userService.hadUserByOffice(officeIdList.get(i))) {
    			return "删除失败, 该机构下面存在用户不允许删除，请先删除用户或者迁移用户！";
    		}
		}
        
        officeService.batchDeleteOffice(officeIdList);
	
		return "删除成功";
	}
	
	/**
	 * 判断是否存在子机构
	 * @param officeId （参数是不可空）
	 * @return 
	 * @author lgx
	 * Date:2017年5月19日；
	 */
	public boolean hadChild(String officeId){
		if (StringUtils.isBlank(officeId)) {
			return false;
		}
		Office parent = new Office();
		parent.setId(officeId);
		Office o = new Office();
		o.setParent(parent);
		o.setShowMyOffice(false);
		o.setIncludeParentId(false);
		List<Office> childList  = officeService.findList(o);
		if (childList != null && childList.size() > 0) {
			return true;
		}
		
		return false;
	}
	
	/**
	 * 判断机构下是否存在用户
	 * @param officeId 
	 * @return 
	 * @author lgx
	 * Date:2017年5月22日；
	 */
	public boolean hadUser(String officeId){
		return userService.hadUserByOffice(officeId);
	}
}
